package com.rapida.net;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Observable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

/**
 * Created by mm on 2015/1/17.
 */
public class NetworkHelper extends BroadcastReceiver {
	private static NetworkHelper sInstance = null;
	private Context mContext;
	private boolean mIsNetwork = true;
	private NETWORK_TYPE mNetworkType = NETWORK_TYPE.NULL;
	private final NetworkStateObservable mStateObservable = new NetworkStateObservable();
	public enum NETWORK_TYPE {NULL, MOBILE, WIFI};

	public interface NetworkStateObserver {
		public void onChanged(boolean network, NETWORK_TYPE type);
	}

	private static class NetworkStateObservable extends Observable<NetworkStateObserver> {

		public void notifyStateChanged(boolean network, NETWORK_TYPE type) {
			synchronized (mObservers) {
				for (int i = mObservers.size() - 1; i >= 0; i--) {
					mObservers.get(i).onChanged(network, type);
				}
			}
		}
	}

	public static NetworkHelper getInstance(Context context) {
		if (sInstance == null) {
			sInstance = new NetworkHelper(context);
		}
		return sInstance;
	}

	public void onDestory() {
		mContext.unregisterReceiver(this);
	}

	private NetworkHelper(Context context) {
		mContext = context;
		IntentFilter filter = new IntentFilter();
		filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
		mContext.registerReceiver(this, filter);
	}

	public void registerStateObserver(NetworkStateObserver observer) {
		mStateObservable.registerObserver(observer);
	}

	public void unregisterStateObserver(NetworkStateObserver observer) {
		mStateObservable.unregisterObserver(observer);
	}

	public void notifyStateChanged(boolean network, NETWORK_TYPE type) {
		mStateObservable.notifyStateChanged(network, type);
	}

	public boolean IsNetwork() {
		checkNetwork(mContext);
		return mIsNetwork;
	}

	public NETWORK_TYPE getNetworkType() {
		checkNetwork(mContext);
		return mNetworkType;
	}

	private void checkNetwork(Context context) {
		mIsNetwork = false;
		mNetworkType = NETWORK_TYPE.NULL;
		ConnectivityManager manager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
		if (manager.getActiveNetworkInfo() != null) {
			mIsNetwork = manager.getActiveNetworkInfo().isAvailable();
		}
		if (mIsNetwork) {
			NetworkInfo.State mobile = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
			if (mobile == NetworkInfo.State.CONNECTED || mobile == NetworkInfo.State.CONNECTING) {
				mNetworkType = NETWORK_TYPE.MOBILE;
			}
			NetworkInfo.State wifi = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
			if (wifi == NetworkInfo.State.CONNECTED || wifi == NetworkInfo.State.CONNECTING) {
				mNetworkType = NETWORK_TYPE.WIFI;
			}
		}
	}

	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		if ("android.net.conn.CONNECTIVITY_CHANGE".equals(action)) {
			checkNetwork(context);
			notifyStateChanged(mIsNetwork, mNetworkType);
		}
	}
}
